#ifndef __DEVICE_IDE_H
#define __DEVICE_IDE_H
#include "global.h"
#include "list.h"
#include "bitmap.h"
#include "sync.h"
#include "super_block.h"

/* 分区结构 */
struct partition {
    uint32_t start_lba; // 起始扇区
    uint32_t sec_cnt;   // 扇区数
    struct disk *my_disk;   // 分区所属硬盘
    struct list_elem part_tag;  // 用于队列中的标记
    char name[8];
    struct super_block *sb; // 本分区超级块
    struct bitmap block_bitmap; // 块位图
    struct bitmap inode_bitmap; // i结点位图
    struct list open_inodes;    // 本分区打开的i结点队列
};

/* 硬盘结构 */
struct disk {
    char name[8];
    struct ide_channel *my_channel; // 此硬盘归属哪个ide通道
    uint8_t dev_no;     // 主盘0, 从盘1
    struct partition prim_parts[4]; // 主分区最多4
    struct partition logic_parts[8]; // 支持最多8个逻辑分区
};

/* ata通道结构 */
struct ide_channel {
    char name[8];
    uint16_t port_base; // 起始端口
    uint8_t irq_no;     // 中断号
    struct lock lock;   // 通道锁
    bool expecting_intr;// 表示等待硬盘的中断
    struct semaphore disk_done; // 用于阻塞,唤醒驱动程序,驱动程序向硬盘发送命令后，在等待硬盘工作期间可以通过此信号量阻塞自己，避免干等着浪费 CPU。等硬盘工作完成后会发出中断，中断处理程序通过此信号量将硬盘驱动程序唤醒。
    struct disk devices[2]; // 一个通道上连接两个硬盘,一主一从
};

extern uint8_t channel_cnt;
extern struct ide_channel channels[2];
extern struct list partition_list;

void ide_init(void);
void ide_read(struct disk *hd, uint32_t lba, void *buf, uint32_t sec_cnt);
void ide_write(struct disk *hd, uint32_t lba, void *buf, uint32_t sec_cnt);

#endif